﻿using MapleLeaf.Core.Dto;
using MapleLeaf.Core.FriendlyException;
using MapleLeaf.Core.Serilog;
using Newtonsoft.Json;

namespace MapleLeaf.WebApi.CookBook {
    /// <summary>
    /// 全局异常中间件
    /// </summary>
    public class ExceptionMiddleware {
        private readonly RequestDelegate next;
        private IHostEnvironment environment;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="next"></param>
        /// <param name="environment"></param>
        public ExceptionMiddleware(RequestDelegate next, IHostEnvironment environment) {
            this.next = next;
            this.environment = environment;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task Invoke(HttpContext context) {
            //try {
            //    Console.WriteLine(context.Request.Path);
            //    await next.Invoke(context);
            //} catch (Exception e) {

            //    await HandleException(context, e);
            //   // await context.Response.WriteAsync(e.Message);
            //    Console.WriteLine(e.Message);
            //}

            try {
                Console.WriteLine(context.Request.Path);
                await next.Invoke(context);
            } catch (Exception e) {
                if (e is ApiFriendlyException exception) {
                    await HandleApiFriendlyException(context, exception);
                } else {
                    await HandleException(context, e);
                }
                Console.WriteLine(e.Message);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <param name="ex"></param>
        /// <returns></returns>
        private async Task HandleException(HttpContext context, Exception ex) {
            context.Response.ContentType = "text/json;charset=utf-8;";
            ApiResult error = new() { code = 500 };
            context.Response.StatusCode = 500;
            if (environment.IsDevelopment()) {
                error.msg = ex.Message;
            } else {
                error.msg = "系统内部错误,请联系系统管理员！";
            }
            SerilogLogHelper.WriteSystemLog(ex.Message);
            await context.Response.WriteAsync(JsonConvert.SerializeObject(error));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        /// <param name="ex"></param>
        /// <returns></returns>
        private async Task HandleApiFriendlyException(HttpContext context, ApiFriendlyException ex) {
            context.Response.ContentType = "text/json;charset=utf-8;";
            if (ex.ExceptionCode == 0) {
                ex.ExceptionCode = context.Response.StatusCode;
            }
            ApiResult error = new() {
                code = ex.ExceptionCode,
                msg = ApiFriendlyException.GetDescriptionByCode(ex.ExceptionCode)
            };
            await context.Response.WriteAsync(JsonConvert.SerializeObject(error));
        }
    }
}
